package JAVACORE_TRAINING.OOPs.GENERICS.SAMPLE02.GENERICS_WILDCARDS.EXAMPLE03;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class ShareControllerOfGenerics {

    // Nghiệp vụ vẽ đường tròn
    static void drawCircle(List<? extends CircleShape> objEx, 
    					List<? super CircleShape> objSu) {
        CircleShape objCircle = objEx.remove(0);
        objSu.add(objCircle);
    }

    static void drawOctagon(List<? extends OctagonShape> objEx, 
    					List<? super OctagonShape> objSu) {
        OctagonShape objOctagon = objEx.remove(0);
        objSu.add(objOctagon);
    }

    static <T> List<T> MakeList(T obj) {
        List<T> lis = new LinkedList<T>();
        lis.add(obj);
        return lis;
    }

    public static void main(String[] str) {
        // 1.
        List<CircleShape> objCi = MakeList(new CircleShape());
        List<OctagonShape> objOc = MakeList(new OctagonShape());
        List<ChildOctagon> objChildOc = MakeList(new ChildOctagon());

        // 2.
        List<Shape> lisShape = new ArrayList<Shape>();
        List<BaseShape> lisBaseShape = new ArrayList<BaseShape>();
        List<CircleShape> lisCi = new ArrayList<CircleShape>();
        List<OctagonShape> lisOc = new ArrayList<OctagonShape>();

        // 3.
        // a. Okie
        drawCircle(objCi, lisShape); // Okie
        drawCircle(objCi, objCi); // Okie
        drawCircle(objCi, lisBaseShape); // Okie

        drawOctagon(objOc, lisShape); // Okie
        drawOctagon(objChildOc, lisShape); // Okie
        drawOctagon(objChildOc, lisBaseShape); // Okie

        // b. Not Okie
         //drawCircle(lisShape, lisShape); // Errors lisShap ko phai Circle hay
        // kế
        // thừa từ Cirle
        //drawOctagon(lisShape, lisShape); // Errors tuong tu
         //drawOctagon(objChildOc, objChildOc); // Errors chilOc ko phỉa bố cuar
        // Oc

        /*
         * Tổng kết: 
         * + ? extends T : Đối tượng ? phải kế thừa từ T hoặc là chính T. 
         * + ? super T: Đối tượng ? phải là đối tượng cha của T hoặc là chínhT (ko nhận các đối tượng con của T).
         */
    }
}

class CircleShape extends Shape {
}

class OctagonShape extends Shape {
}

class ChildOctagon extends OctagonShape {
}

class Shape extends BaseShape {
}

class BaseShape {
}